<template>
  <view class="htz-image-upload-list">
    <view
      class="htz-image-upload-Item"
      v-for="(item, index) in uploadLists"
      :key="index"
      v-if="!!item"
    >
      <view
        class="htz-image-upload-Item-video"
        v-if="!/.(gif|jpg|jpeg|png|gif|jpg|png)$/i.test(item)"
      >
        <video :disabled="false" :controls="false" :src="item">
          <cover-view
            class="htz-image-upload-Item-video-fixed"
            @click="previewVideo(item)"
          ></cover-view>

          <cover-view
            class="htz-image-upload-Item-del-cover"
            v-if="remove && previewVideoSrc == ''"
            @click="imgDel(index)"
            >×</cover-view
          >
        </video>
      </view>

      <image v-else :src="item" @click="imgPreview(item)"></image>

      <view
        class="htz-image-upload-Item-del"
        v-if="remove"
        @click="imgDel(index)"
        >×</view
      >
    </view>
    <view
      class="htz-image-upload-Item htz-image-upload-Item-add"
      v-if="uploadLists.length < max && add"
      @click="chooseFile"
    >
      +
    </view>
    <view class="preview-full" v-if="previewVideoSrc != ''">
      <video
        :autoplay="true"
        :src="previewVideoSrc"
        :show-fullscreen-btn="false"
      >
        <cover-view class="preview-full-close" @click="previewVideoClose">
          ×
        </cover-view>
      </video>
    </view>

    <view class="progress-box" style="width: 100%" v-if="jdt < 100 && jdt > 0">
      <progress :percent="jdt" show-info stroke-width="3" style="width: 100%" />
    </view>
    <!--  -->
  </view>
</template>

<style>
  .ceshi {
    width: 100%;
    height: 100%;
    position: relative;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-color: #ffffff;
    color: #2c405a;
    opacity: 0.5;
    z-index: 100;
  }
  .progress-box {
    display: flex;
    height: 50rpx;
    margin-bottom: 60rpx;
  }
</style>

<script>
  export default {
    name: 'htz-image-upload',
    props: {
      max: {
        //展示图片最大值
        type: Number,
        default: 1,
      },
      chooseNum: {
        //选择图片数
        type: Number,
        default: 9,
      },
      name: {
        //发到后台的文件参数名
        type: String,
        default: 'file',
      },
      remove: {
        //是否展示删除按钮
        type: Boolean,
        default: true,
      },
      add: {
        //是否展示添加按钮
        type: Boolean,
        default: true,
      },
      disabled: {
        //是否禁用
        type: Boolean,
        default: false,
      },
      sourceType: {
        //选择照片来源 【ps：H5就别费劲了，设置了也没用。不是我说的，官方文档就这样！！！】
        type: Array,
        default: () => ['album', 'camera'],
      },
      action: {
        //上传地址
        type: String,
        default: '',
      },
      headers: {
        //上传的请求头部
        type: Object,
        default: () => {},
      },
      formData: {
        //HTTP 请求中其他额外的 form data
        type: Object,
        default: () => {},
      },
      compress: {
        //是否需要压缩
        type: Boolean,
        default: true,
      },
      quality: {
        //压缩质量，范围0～100
        type: Number,
        default: 80,
      },
      value: {
        //受控图片列表
        type: Array,
        default: () => [],
      },
      uploadSuccess: {
        default: (res) => {
          return {
            success: false,
            url: '',
          };
        },
      },
      mediaType: {
        //文件类型 image/video/all
        type: String,
        default: 'image',
      },
      maxDuration: {
        //拍摄视频最长拍摄时间，单位秒。最长支持 60 秒。 (只针对拍摄视频有用)
        type: Number,
        default: 60,
      },
      camera: {
        //'front'、'back'，默认'back'(只针对拍摄视频有用)
        type: String,
        default: 'back',
      },
      videoSize: {
        // 视频上传大小限制
        type: Number,
        default: 524288000,
      },
      limitVideoSize: {
        // 是否限制视频上传大小
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        uploadLists: [],
        mediaTypeData: ['image', 'video', 'all'],
        previewVideoSrc: '',
        jdt: 0,
        msg: null,
      };
    },
    mounted: function () {
      this.$nextTick(function () {
        this.uploadLists = this.value;
        if (this.mediaTypeData.indexOf(this.mediaType) == -1) {
          uni.showModal({
            title: '提示',
            content: 'mediaType参数不正确',
            showCancel: false,
            success: function (res) {
              if (res.confirm) {
                //console.log('用户点击确定');
              } else if (res.cancel) {
                //console.log('用户点击取消');
              }
            },
          });
        }
      });
    },
    watch: {
      value(val, oldVal) {
        //console.log('value',val, oldVal)
        this.uploadLists = val;
      },
    },
    methods: {
      previewVideo(src) {
        this.previewVideoSrc = src;
        // this.previewVideoSrc =
        // 	'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-fbd63a76-dc76-485c-b711-f79f2986daeb/ba804d82-860b-4d1a-a706-5a4c8ce137c3.mp4'
      },
      previewVideoClose() {
        this.previewVideoSrc = '';
        console.log('previewVideoClose', this.previewVideoSrc);
      },
      imgDel(index) {
        uni.showModal({
          title: '提示',
          content: '您确定要删除么?',
          success: (res) => {
            if (res.confirm) {
              // this.uploadLists.splice(index, 1)
              // this.$emit("input", this.uploadLists);
              // this.$emit("imgDelete", this.uploadLists);
              let delUrl = this.uploadLists[index];
              this.uploadLists.splice(index, 1);
              this.$emit('input', this.uploadLists);
              this.$emit('imgDelete', {
                del: delUrl,
                tempFilePaths: this.uploadLists,
              });
            } else if (res.cancel) {
            }
          },
        });
      },
      imgPreview(index) {
        var imgData = this.uploadLists.filter((item) =>
          /.(gif|jpg|jpeg|png|gif|jpg|png)$/i.test(item),
        ); //只预览图片的
        uni.previewImage({
          urls: imgData,
          current: index,
          loop: true,
        });
      },
      chooseFile() {
        if (this.disabled) {
          return false;
        }
        switch (this.mediaTypeData.indexOf(this.mediaType)) {
          case 1: //视频
            this.videoAdd();
            break;
          case 2: //全部
            uni.showActionSheet({
              itemList: ['相册', '视频'],
              success: (res) => {
                if (res.tapIndex == 1) {
                  this.videoAdd();
                } else if (res.tapIndex == 0) {
                  this.imgAdd();
                }
              },
              fail: (res) => {
                console.log(res.errMsg);
              },
            });
            break;
          default: //图片
            this.imgAdd();
            break;
        }

        //if(this.mediaType=='image'){
      },
      videoAdd() {
        console.log('videoAdd');
        let nowNum = Math.abs(this.uploadLists.length - this.max);
        let thisNum = this.chooseNum > nowNum ? nowNum : this.chooseNum; //可选数量
        uni.chooseVideo({
          compressed: this.compress,
          sourceType: this.sourceType,
          camera: this.camera,
          maxDuration: this.maxDuration,
          success: (res) => {
            console.log('视频上传’', res.size);
            if (this.limitVideoSize && res.size > this.videoSize) {
              uni.showModal({
                title: '提示',
                content: '请上传小于500MB大小的视频',
                showCancel: false,
                success: (res) => {
                  if (res.confirm) {
                  } else if (res.cancel) {
                  }
                },
              });
              return;
            }
            this.chooseSuccessMethod([res.tempFilePath], 1);
          },
        });
      },
      imgAdd() {
        console.log('imgAdd');
        let nowNum = Math.abs(this.uploadLists.length - this.max);
        let thisNum = this.chooseNum > nowNum ? nowNum : this.chooseNum; //可选数量

        // #ifdef APP-PLUS
        if (this.sourceType.length > 1) {
          uni.showActionSheet({
            itemList: ['拍摄', '从手机相册选择'],
            success: (res) => {
              if (res.tapIndex == 1) {
                this.appGallery(thisNum);
              } else if (res.tapIndex == 0) {
                this.appCamera();
              }
            },
            fail: (res) => {
              console.log(res.errMsg);
            },
          });
        }
        if (
          this.sourceType.length == 1 &&
          this.sourceType.indexOf('album') > -1
        ) {
          this.appGallery(thisNum);
        }

        if (
          this.sourceType.length == 1 &&
          this.sourceType.indexOf('camera') > -1
        ) {
          this.appCamera();
        }
        // #endif
        //#ifndef APP-PLUS
        uni.chooseImage({
          count: thisNum,
          sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
          sourceType: this.sourceType,
          success: (res) => {
            this.chooseSuccessMethod(res.tempFilePaths, 0);
            //console.log('tempFiles', res)
            // if (this.action == '') { //未配置上传路径
            // 	this.$emit("chooseSuccess", res.tempFilePaths);
            // } else {
            // 	if (this.compress && (res.tempFiles[0].size / 1024 > 1025)) { //设置了需要压缩 并且 文件大于1M，进行压缩上传
            // 		this.imgCompress(res.tempFilePaths);
            // 	} else {
            // 		this.imgUpload(res.tempFilePaths);
            // 	}
            // }
          },
        });
        // #endif
      },
      appCamera() {
        var cmr = plus.camera.getCamera();
        var res = cmr.supportedImageResolutions[0];
        var fmt = cmr.supportedImageFormats[0];
        //console.log("Resolution: " + res + ", Format: " + fmt);
        cmr.captureImage(
          (path) => {
            //alert("Capture image success: " + path);
            this.chooseSuccessMethod([path], 0);
          },
          (error) => {
            //alert("Capture image failed: " + error.message);
            console.log('Capture image failed: ' + error.message);
          },
          {
            resolution: res,
            format: fmt,
          },
        );
      },
      appGallery(maxNum) {
        plus.gallery.pick(
          (res) => {
            this.chooseSuccessMethod(res.files, 0);
          },
          function (e) {
            //console.log("取消选择图片");
          },
          {
            filter: 'image',
            multiple: true,
            maximum: maxNum,
          },
        );
      },
      chooseSuccessMethod(filePaths, type) {
        if (this.action == '') {
          //未配置上传路径
          this.$emit('chooseSuccess', filePaths, type); //filePaths 路径 type 0 为图片 1为视频
        } else {
          if (type == 1) {
            this.imgUpload(filePaths);
          } else {
            // if (this.compress) { //设置了需要压缩
            // 	this.imgCompress(filePaths);
            // } else {
            this.imgUpload(filePaths);
            // }
          }
        }
      },
      imgCompress(tempFilePaths) {
        uni.showLoading({
          title: '压缩中...',
        });

        let compressImgs = [];
        let results = [];
        tempFilePaths.forEach((item, index) => {
          compressImgs.push(
            new Promise((resolve, reject) => {
              // #ifndef H5
              uni.compressImage({
                src: item,
                quality: this.quality,
                success: (res) => {
                  //console.log('compressImage', res.tempFilePath)
                  results.push(res.tempFilePath);
                  resolve(res.tempFilePath);
                },
                fail: (err) => {
                  //console.log(err.errMsg);
                  reject(err);
                },
                complete: () => {
                  //uni.hideLoading();
                },
              });
              // #endif
              // #ifdef H5
              this.canvasDataURL(
                item,
                {
                  quality: this.quality / 100,
                },
                (base64Codes) => {
                  //this.imgUpload(base64Codes);
                  results.push(base64Codes);
                  resolve(base64Codes);
                },
              );
              // #endif
            }),
          );
        });
        Promise.all(compressImgs) //执行所有需请求的接口
          .then((results) => {
            uni.hideLoading();
            console.log('imgUpload', results);
            this.imgUpload(results);
          })
          .catch((res, object) => {
            uni.hideLoading();
          });
      },
      async imgUpload(tempFilePaths) {
        uni.showLoading({
          title: '上传中...',
          mask: true,
        });

        for (const i of tempFilePaths) {
          const res = await this.uploadfiles(i);
          if (res.code == 200) {
            this.value.push(res.imgUrl ? res.imgUrl : i);
          } else {
            uni.showModal({
              title: '提示',
              content: res.message || '服务器出错',
              success: (res) => {
                if (res.confirm) {
                } else if (res.cancel) {
                }
              },
            });
          }
          this.$emit('uploadSuccess', res);
        }
        setTimeout(function () {
          uni.hideLoading();
        }, 100);
        this.$emit('item', this.value);
      },
      uploadfiles(item) {
        let that = this;
        const acc_token = uni.getStorageSync('wxlsToken');
        const header = { Authorization: `Bearer ${acc_token}` };
        return new Promise((resolve, reject) => {
          let uploadmain = uni.uploadFile({
            url: this.action, //仅为示例，非真实的接口地址
            filePath: item,
            name: this.name,
            timeout: 600000,
            header,
            success: (uploadFileRes) => {
              try {
                resolve(JSON.parse(uploadFileRes.data));
              } catch (e) {
                resolve(uploadFileRes.data);
              }
            },
            fail: (err) => {
              reject(err);
            },
          });
          uploadmain.onProgressUpdate((res) => {
            that.jdt = res.progress;
            if (that.jdt >= 100) {
              uni.showLoading({
                title: '等待数据校验完成',
                mask: true,
              });
            }
          });
        });
      },
      canvasDataURL(path, obj, callback) {
        var img = new Image();
        img.src = path;
        img.onload = function () {
          var that = this;
          // 默认按比例压缩
          var w = that.width,
            h = that.height,
            scale = w / h;
          w = obj.width || w;
          h = obj.height || w / scale;
          var quality = 0.8; // 默认图片质量为0.8
          //生成canvas
          var canvas = document.createElement('canvas');
          var ctx = canvas.getContext('2d');
          // 创建属性节点
          var anw = document.createAttribute('width');
          anw.nodeValue = w;
          var anh = document.createAttribute('height');
          anh.nodeValue = h;
          canvas.setAttributeNode(anw);
          canvas.setAttributeNode(anh);
          ctx.drawImage(that, 0, 0, w, h);
          // 图像质量
          if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
            quality = obj.quality;
          }
          // quality值越小，所绘制出的图像越模糊
          var base64 = canvas.toDataURL('image/jpeg', quality);
          // 回调函数返回base64的值
          callback(base64);
        };
      },
    },
  };
</script>

<style>
  .preview-full {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    z-index: 1002;
  }

  .preview-full video {
    width: 100%;
    height: 100%;
    z-index: 1002;
  }

  .preview-full-close {
    position: fixed;
    right: 32rpx;
    top: 25rpx;
    width: 80rpx;
    height: 80rpx;
    line-height: 60rpx;
    text-align: center;
    z-index: 1003;
    /* 	background-color: #808080; */
    color: #fff;
    font-size: 65rpx;
    font-weight: bold;
    text-shadow: 1px 2px 5px rgb(0 0 0);
  }

  /* .preview-full-close-before,
	.preview-full-close-after {
		position: absolute;
		top: 50%;
		left: 50%;
		content: '';
		height: 60rpx;
		margin-top: -30rpx;
		width: 6rpx;
		margin-left: -3rpx;
		background-color: #FFFFFF;
		z-index: 20000;
	}

	.preview-full-close-before {
		transform: rotate(45deg);

	}

	.preview-full-close-after {
		transform: rotate(-45deg);

	} */

  .htz-image-upload-list {
    display: flex;
    flex-wrap: wrap;
  }

  .htz-image-upload-Item {
    width: 160rpx;
    height: 160rpx;
    line-height: 160rpx;
    margin: 8rpx;
    border-radius: 10rpx;
    position: relative;
  }

  .htz-image-upload-Item image {
    width: 100%;
    height: 100%;
    border-radius: 10rpx;
  }

  .htz-image-upload-Item-video {
    width: 100%;
    height: 100%;
    border-radius: 10rpx;
    position: relative;
  }

  .htz-image-upload-Item-video-fixed {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    border-radius: 10rpx;
    z-index: 996;
  }

  .htz-image-upload-Item video {
    width: 100%;
    height: 100%;
    border-radius: 10rpx;
  }

  .htz-image-upload-Item-add {
    font-size: 105rpx;
    /* line-height: 160rpx; */
    text-align: center;
    border: 1px dashed #bddbed;
    color: #bddbed;
  }

  .htz-image-upload-Item-del {
    background-color: #f5222d;
    font-size: 24rpx;
    position: absolute;
    width: 35rpx;
    height: 35rpx;
    line-height: 35rpx;
    text-align: center;
    top: 0;
    right: 0;
    z-index: 997;
    color: #fff;
  }

  .htz-image-upload-Item-del-cover {
    background-color: #f5222d;
    font-size: 24rpx;
    position: absolute;
    width: 35rpx;
    height: 35rpx;
    text-align: center;
    top: 0;
    right: 0;
    color: #fff;
    /* #ifdef APP-PLUS */
    line-height: 25rpx;
    /* #endif */
    /* #ifndef APP-PLUS */
    line-height: 35rpx;
    /* #endif */
    z-index: 997;
  }
</style>
